#include "../source/server.hpp"


//理解了channel
void HandleClose(Channel* channel)
{
    std::cout << "Close: " << channel->Fd() << std::endl;
    channel->Remove();//移除监控
    delete channel;
}
void HandleRead(Channel* channel)
{
    int fd = channel->Fd();
    char buf[1024] = {0};
    int ret = recv(fd, buf, 1023, 0);
    if (ret <= 0)//要么关闭了要么出错了
    {
        HandleClose(channel);//关闭释放
        return;
    }
    channel->EnableWrite();//启动可写事件
    std::cout << buf << std::endl;
}
void HandleWrite(Channel* channel)
{
    int fd = channel->Fd();
    const char* data = "天气还不错";
    int ret = send(fd, data, strlen(data), 0);
    if (ret < 0)
    {
        HandleClose(channel);
        return;
    }
    channel->DisableWrite();//关闭写监控
}

void HandleError(Channel* channel)
{
    HandleClose(channel);
}
void HandleEvent(Channel* channel)
{
    std::cout << "有了一个事件" << std::endl;
}
void Acceptor(Poller* poller, Channel* lst_channel)
{
    int fd = lst_channel->Fd();
    int newfd = accept(fd, NULL, NULL);
    DBG_LOG("获得一个新的连接");
    if (newfd < 0)
        return;
    Channel* channel = new Channel(poller, newfd);                      //设置新连接fd的事件
    channel->SetReadCallback(std::bind(HandleRead, channel));           //为通信套接字设置可读事件的回调函数
    channel->SetWriteCallback(std::bind(HandleWrite, channel));         //可写事件的回调函数
    channel->SetCloseCallback(std::bind(HandleClose, channel));         //关闭事件的回调函数
    channel->SetErrorCallback(std::bind(HandleError, channel));         //错误事件的回调函数
    channel->SetEventCallback(std::bind(HandleEvent, channel));         //任意事件的回调函数
    channel->EnableRead();
}
int main()
{
    Poller poller;
    Socket lst_sock;
    bool ret = lst_sock.CreateServer(8085);
    //为监听套接字，创建一个Channel进行事件的管理，以及事件的处理
    Channel channel(&poller, lst_sock.Fd());//此时还是监听套接字
    channel.SetReadCallback(std::bind(Acceptor, &poller, &channel));//回调中，获取新连接，为新连接创建Channel并且添加监控
    channel.EnableRead();//启动监听的可读事件监控
    while (1)
    {
        std::vector<Channel*> actives;
        poller.Poll(&actives);
        for (auto& a : actives)
        {
            a->HandleEvent();//看你触发了哪个事件，则调用哪个事件的回调函数
        }
    }
    lst_sock.Close();
    return 0;
}